package org.su.generalmvc.validate;

import org.su.generalmvc.IModel;
import org.apache.commons.lang.StringUtils;
import sun.net.util.IPAddressUtil;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * 错误信息处理类。保存和处理错误信息
 * 
 * @author yangchuan
 * @CreateTime 2010-8-30 下午05:07:55
 * 
 */
public class Errors extends Validater implements IModel {

	private boolean success = true;
	private HashMap<String, String> fieldErrors;
	/**
	 * 全局信息，不一定是错误
	 */
	private HashMap<String, String> globalErrors;
	private HashMap<String, Object> model;

	public Errors() {
		// this.fieldErrors = new HashMap<String, String>();
		// this.globalErrors = new HashMap<String, String>();
		this.model = new HashMap<String, Object>();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#addGlobalErrors(java.lang.String,
	 *      java.lang.String)
	 */
	public String addGlobalErrors(String key, String value) {
		if (globalErrors == null) {
			globalErrors = new HashMap<String, String>();
			model.put("globalErrors", globalErrors);
		} else {
			String v = globalErrors.get(key);
			if (v != null) {
				value = v + ";" + value;
			}
		}
		
		if ("error".equals(key)) {
			success = false;
		}

		return globalErrors.put(key, value);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#getGlobalErrors(java.lang.Object)
	 */
	public String getGlobalErrors(Object key) {
		if (globalErrors == null)
			return null;

		return globalErrors.get(key);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#addFieldErrors(java.lang.String,
	 *      java.lang.String)
	 */
	public String addFieldErrors(String key, String value) {
		if (fieldErrors == null) {
			fieldErrors = new HashMap<String, String>();
			model.put("fieldErrors", fieldErrors);
		} else {
			String v = fieldErrors.get(key);
			if (v != null) {
				value = v + ";" + value;
			}
		}
		
		success = false;
		return fieldErrors.put(key, value);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#getFieldErrors(java.lang.Object)
	 */
	public String getFieldErrors(Object key) {
		if (fieldErrors != null) {
			return fieldErrors.get(key);
		}

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#isEmpty()
	 */
	public boolean isEmpty() {
		return model.isEmpty();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#getFieldErrors()
	 */
	public HashMap<String, String> getFieldErrors() {
		return fieldErrors;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#getGlobalErrors()
	 */
	public HashMap<String, String> getGlobalErrors() {
		return globalErrors;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#addInfo(java.lang.String)
	 */
	public void addInfo(String info) {
		addGlobalErrors("info", info);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#addWarning(java.lang.String)
	 */
	public void addWarning(String info) {
		addGlobalErrors("warning", info);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#addError(java.lang.String)
	 */
	public void addError(String info) {
		addGlobalErrors("error", info);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#addSuccess(java.lang.String)
	 */
	public void addSuccess(String msg) {
		addGlobalErrors("success", msg);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#setData(java.lang.Object)
	 */
	public void setData(Object json) {
		addData("data", json);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#addData(java.lang.String,
	 *      java.lang.Object)
	 */
	public void addData(String key, Object value) {
		model.put(key, value);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#getErrors()
	 */
	public HashMap<String, ?> getErrors() {
		return model;
	}

	@Override
	public Map<String, ?> getModel() {
		return model;
	}

	/** **********************************验证函数************************************ */

	public static String REQUIRE_MSG = "不能为空.";
	public static String EMAIL_MSG = "邮箱格式不正确.";
	public static String PHONE_MSG = "电话号码格式不正确.";

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateRequire(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateRequire(String fieldId, String value, String msg) {
		return addFieldErrors(fieldId, msg, StringUtils.isNotEmpty(value));
	}

	private boolean addFieldErrors(String fieldId, String msg, boolean result) {
		if (!result) {
			this.addFieldErrors(fieldId, msg);
		}

		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateEmail(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateEmail(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(email, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validatePhone(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validatePhone(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(phone, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateMulPhone(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateMulPhone(String fieldId, String value, String msg) {
		return this
				.addFieldErrors(fieldId, msg, validateMatch(mulPhone, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateMobile(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateMobile(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(mobile, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateUrl(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateUrl(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(Url, value));

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateIdCard(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateIdCard(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(IdCard, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateCurrency(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateCurrency(String fieldId, String value, String msg) {
		return this
				.addFieldErrors(fieldId, msg, validateMatch(Currency, value));

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateIP(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateIP(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, (IPAddressUtil
				.isIPv4LiteralAddress(value) || IPAddressUtil
				.isIPv6LiteralAddress(value)));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateNumber(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateNumber(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(_number, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateZip(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateZip(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(Zip, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateQQ(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateQQ(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(QQ, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateInteger(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateInteger(String fieldId, String value, String msg) {
		return this
				.addFieldErrors(fieldId, msg, validateMatch(_integer, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validatePositiveInteger(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validatePositiveInteger(String fieldId, String value,
			String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(positiveInteger,
				value));

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateDouble(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateDouble(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(_double, value));

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateEnglish(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateEnglish(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(english, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateChiniese(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateChiniese(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg, validateMatch(chinese, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateIsRange(java.lang.String, long,
	 *      long, long, java.lang.String)
	 */
	public boolean validateIsRange(String fieldId, long value, long min,
			long max, String msg) {
		return this.addFieldErrors(fieldId, msg, (value > min && value < max));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateIsRange(java.lang.String,
	 *      double, double, double, java.lang.String)
	 */
	public boolean validateIsRange(String fieldId, double value, double min,
			double max, String msg) {
		return this.addFieldErrors(fieldId, msg, (value > min && value < max));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateIsRange(java.lang.String, int,
	 *      int, int, java.lang.String)
	 */
	public boolean validateIsRange(String fieldId, int value, int min, int max,
			String msg) {
		return this.addFieldErrors(fieldId, msg, (value > min && value < max));

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateIsRange(java.lang.String,
	 *      java.lang.Long, java.lang.Long, java.lang.Long, java.lang.String)
	 */
	public boolean validateIsRange(String fieldId, Long value, Long min,
			Long max, String msg) {
		return validateIsRange(fieldId, value.longValue(), min.longValue(), max
				.longValue(), msg);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateIsRange(java.lang.String,
	 *      java.lang.Double, java.lang.Double, java.lang.Double,
	 *      java.lang.String)
	 */
	public boolean validateIsRange(String fieldId, Double value, Double min,
			Double max, String msg) {
		return validateIsRange(fieldId, value.doubleValue(), min.doubleValue(),
				max.doubleValue(), msg);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateIsRange(java.lang.String,
	 *      java.lang.Integer, java.lang.Integer, java.lang.Integer,
	 *      java.lang.String)
	 */
	public boolean validateIsRange(String fieldId, Integer value, Integer min,
			Integer max, String msg) {
		return validateIsRange(fieldId, value.intValue(), min.intValue(), max
				.intValue(), msg);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#validateAccountId(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	public boolean validateAccountId(String fieldId, String value, String msg) {
		return this.addFieldErrors(fieldId, msg,
				validateMatch(AccountId, value));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ssh.generalmvc.web.validate.IModel#setRedirect(java.lang.String)
	 */
	public void setRedirect(String url) {
		model.put(KEY_REDIRECT, url);
	}

	@Override
	public void clear() {
		model.clear();
		
		if (fieldErrors != null) {
			model.put("fieldErrors", fieldErrors);
		}
		
		if (globalErrors != null) {
			model.put("globalErrors", globalErrors);
		}
	}

	@Override
	public void put(String key, Object value) {
		model.put(key, value);
	}

	@Override
	public Object get(String key) {
		return model.get(key);
	}
	
	public boolean isError() {
		return !success;
	}
	
	
	/**
	 * 设置输入流
	 * @param in
	 */
	public void setInputStream(InputStream in){
		model.put("model_inputstream", in);
	}
	
	/**
	 * 获取输入流
	 * @return
	 */
	public InputStream getInputStream(){
		return (InputStream)model.get("model_inputstream");
	}
}
